package com.ds.robot.assistant.job;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.ds.robot.assistant.common.JobHelper;
import com.ds.robot.assistant.component.JsonFileReader;
import com.ds.robot.assistant.component.MessageSender;
import com.ds.robot.assistant.enums.Env;
import com.ds.robot.assistant.service.impl.QxUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 作用：周末值班提醒服务
 * @see DutyNewJob
 * @author WeiShaoying
 * 
 */
@Service
@Slf4j
@SuppressWarnings("all")
public class DutyTipJob extends BaseJob {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private static final DateTimeFormatter DAY_FORMATTER = DateTimeFormatter.ofPattern("yyyy年M月d日");

    private final LoadingCache<String, Boolean> loadingCache;

    private final Map<LocalDateTime, String> dutyScheduleProdMap = readDutySchedule(Env.PROD);
    private final Map<LocalDateTime, String> dutyScheduleTestMap = readDutySchedule(Env.TEST);

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private JsonFileReader jsonFileReader;

    @Autowired
    private QxUserService qxUserService;

    public DutyTipJob() {
        // 构建一个缓存，最大容量1000，过期时间为1分钟
        loadingCache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .expireAfterWrite(1, TimeUnit.HOURS)
                .build(new CacheLoader<String, Boolean>() {
                    @Override
                    public Boolean load(String key) {
                        return false; // 默认值，表示未
                    }
                });
    }

    // @Scheduled(cron = "0 */10 * * * *")
    public void dutyTip() {
        log.info("====值班定时任务开始：" + FORMATTER.format(LocalDateTime.now()));
        executeDutyReminder(Env.TEST);
        executeDutyReminder(Env.PROD);
        log.info("====值班定时任务完成：" + FORMATTER.format(LocalDateTime.now()));
    }

    /**
     * 执行值班任务
     *
     * @param env
     */
    private void executeDutyReminder(Env env) {
        Map<LocalDateTime, String> dutyScheduleMap = env.equals(Env.PROD) ? this.dutyScheduleProdMap : this.dutyScheduleTestMap;
        for (Map.Entry<LocalDateTime, String> entry : dutyScheduleMap.entrySet()) {
            LocalDateTime dutyTime = entry.getKey();
            String personName = entry.getValue();

            // 检查当前时间是否匹配，到小时：生产
            if (dutyTime.truncatedTo(ChronoUnit.HOURS).equals(LocalDateTime.now().truncatedTo(ChronoUnit.HOURS))) {
                // 分钟：测试
                // if (dutyTime.truncatedTo(ChronoUnit.MINUTES).equals(LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES))) {
                // 构建消息
                String message = buildMessage(dutyTime, personName);
                String key = env.name() + message;
                // 线程安全
                try {
                    if (!loadingCache.get(key)) {
                        log.info(message);
                        // 发送
                        messageSender.sendMessage(message, env);
                        // 线程安全地更新缓存
                        loadingCache.put(key, true);
                    } else {
                        // 已经发送过
                        log.info("......");
                    }
                } catch (ExecutionException e) {
                    log.error("缓存操作异常", e);
                }
            }
        }
    }

    /**
     * 构建消息
     *
     * @param dutyTime   值班时间
     * @param personName 值班人
     * @return
     */
    private String buildMessage(LocalDateTime dutyTime, String personName) {
        // 构建消息体
        StringBuilder builder = new StringBuilder();
        builder.append("# 值班提醒\n")
                .append("温馨提示：").append(dutyTime.format(DAY_FORMATTER))
                .append(" <font color=\"warning\">**").append(personName).append("**</font> 值班，辛苦做好群问题的解答和支持工作~\n")
                .append(" > 上午：<font color=\"info\">**08:00-15:00**</font>\n")
                .append(" > 下午：<font color=\"info\">**15:00-22:00**</font>\n")
                .append("\n## 参考文档\n")
                .append(" > [1.店长手册](https://doc.weixin.qq.com/pdf/d3_AWQApgY4ALE73xcxhWGQHqId8LhQh?scode=AG0A3QfYAA0Ilxf3fl)\n")
                .append(" > [2.常见问题收集表](https://doc.weixin.qq.com/sheet/e3_AaMAzwa-AMIaua51arvRFOYV2Th31?scode=AG0A3QfYAA0jAKdaC2)");
        //
        super.appendUserId(personName, builder, log);
        return builder.toString();
    }


    private static Map<LocalDateTime, String> readDutySchedule(Env env) {
        Map<LocalDateTime, String> scheduleMap = new ConcurrentHashMap<>();

        ClassPathResource resource = new ClassPathResource(env.equals(Env.PROD) ? "dutyProd.data" : "dutyTest.data");

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null && StringUtils.hasText(line)) {
                String[] parts = line.trim().split(",");
                if (parts.length == 2) {
                    LocalDateTime time = LocalDateTime.parse(parts[0], FORMATTER);
                    String name = parts[1];
                    scheduleMap.put(time, name);
                } else {
                    log.warn("忽略无效行: {}", line);
                }
            }
        } catch (IOException e) {
            log.error("读取配置异常", e);
        }
        return scheduleMap;
    }

    public static void main(String[] args) {
        String str = "@魏韶颖 上午，@贺德智 下午";
        List<String> names = JobHelper.extractNameFromStr(str);
        names.forEach(System.out::println);
    }

}
